package com.example.AIstudy.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.example.AIstudy.DTO.RedoRecordDTO;
import com.example.AIstudy.domain.*;
import com.example.AIstudy.exception.AIstudyException;
import com.example.AIstudy.service.CuoTiJiService;
import com.example.AIstudy.service.RedoRecordService;
import com.example.AIstudy.service.UserSkillScoreService;
import com.example.AIstudy.util.MyThread;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.web.bind.annotation.*;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


@RestController
@CrossOrigin
@RequestMapping("/redoRecord")
@Api(tags = "错题巩固记录管理API")
public class RedoRecordController {

    @Autowired
    RedoRecordService redoRecordService;

    @Autowired
    CuoTiJiService cuoTiJiService;

    @Autowired
    AnalyseController analyseController;

    @Autowired
    UserSkillScoreService userSkillScoreService;
    double exponent = Math.log(0.5);
    @ApiOperation("定时任务，每天零点查询用户的错题巩固记录并判断是否需要巩固错题")
    @Scheduled(cron="0 0 0 * * *")
//    @GetMapping()
    public void insertNeedRedoData() throws AIstudyException {
        //获取到上次巩固的所有错题信息
        List<RedoRecordDTO> recordDTOList=redoRecordService.queryLastTimeRedoDetail();
        //获取当前的时间戳
        long currentTimeMillis = System.currentTimeMillis();
        System.out.println(currentTimeMillis);
        System.out.println(exponent);
        //需要巩固的错题ID
        List<Integer>ids=new ArrayList<>();
        //循环遍历，确定今天是否需要巩固
        int size=recordDTOList.size();
        for(int i=0;i<size;i++){
            RedoRecordDTO redoRecordDTO=recordDTOList.get(i);
            //如果本来就是该做，证明在今天之前就需要巩固，不需要重复计算
            if(redoRecordDTO.needRedo)continue;
            //遗忘时间常数根据巩固的次数来确定
            //巩固的次数越多，遗忘时间常数越大，意味着需要更多时间才会忘记
            double forgetRateNum= redoRecordDTO.redoNum;
            //根据遗忘时间常数来获取应该巩固的天数
            Double dateNum= -exponent*forgetRateNum;
            System.out.println(redoRecordDTO.getId());
            System.out.println(dateNum);
            long millisecondsToAdd = (long) (dateNum * 24 * 60 * 60 * 1000L);
            long needRedoTime;
            //根据上次复习的时间戳和隔多少天需要巩固，确定下次需要巩固的时间戳
            if(redoRecordDTO.getRedoTime()!=null){
                needRedoTime =redoRecordDTO.getRedoTime().getTime() + millisecondsToAdd;
            }
            else{
                //如果没有巩固，则根据插入的时间来计算
                needRedoTime =redoRecordDTO.getInsertTime().getTime() + millisecondsToAdd;
            }
            System.out.println(needRedoTime);
            //需要巩固这道错题
            if(needRedoTime<=currentTimeMillis){
                ids.add(redoRecordDTO.getId());
            }
        }
        //更新需要巩固的错题，将需要巩固的字段设置为1
        cuoTiJiService.updateRedoCuoti(ids);
    }
    @ApiOperation("分页获取错题巩固的历史信息，这里没有全部封装完成错题巩固的历史，点进去查看详情的时候，再查询一次即可")
    @GetMapping()
    public IPage<RedoRecordDTO> queryRedoRecord(@ApiParam("用户ID")@RequestParam(value = "stuID") Integer stuID,
                                                @ApiParam("类别列表")@RequestParam(value = "category",required = false) List<String> category,
//                                                @ApiParam("错因ID列表")@RequestParam(value = "falseReasonIDs",required = false) List<Integer> falseReasonIDs,
                                                @ApiParam("最早巩固时间")@RequestParam(value = "minTime",required = false) Timestamp minTime,
                                                @ApiParam("最晚巩固时间")@RequestParam(value = "maxTime",required = false)  Timestamp maxTime,
//                                                @ApiParam("时间排序方式，可以是ASC或者DESC")@RequestParam(value = "order",required = false)  String order,
                                                @ApiParam("页码")@RequestParam(defaultValue = "0")Integer pageNum,
                                                @ApiParam("每页记录数") @RequestParam(defaultValue = "10")Integer pageSize){
        Map<String,Object> condition=new HashMap<>();
        condition.put("stuID", stuID);
        if(category!=null) {
            condition.put("category",category);
        }
//        if(falseReasonIDs!=null) {
//            condition.put("falseReasonIDs",falseReasonIDs);
//        }
        if(minTime!=null) {
            condition.put("minTime",minTime);
        }if(maxTime!=null) {
            condition.put("maxTime",maxTime);
        }
//        if(order!=null) {
//            condition.put("order",order);
//        }
        return redoRecordService.queryRedoRecord(condition, pageNum,pageSize);
    }
    @ApiOperation("获取错题巩固的详细信息")
    @GetMapping("/detail/v1")
    public RedoRecord queryRedoRecord(@ApiParam("用户ID")@RequestParam(value = "stuID") Integer stuID,
                                      @ApiParam("记录ID")@RequestParam(value = "recordID") Integer recordID) throws AIstudyException{
       return redoRecordService.getRecordDetail(recordID);
    }

    @ApiOperation("获取错题巩固的详细信息,以cuoti的json格式返回")
    @GetMapping("/detail/v2")
    public CuoTiJi queryRedoRecordByCuotiJson(@ApiParam("用户ID")@RequestParam(value = "stuID") Integer stuID,
                                      @ApiParam("记录ID")@RequestParam(value = "recordID") Integer recordID) throws AIstudyException{
        return redoRecordService.getRecordDetailWithCuotiJson(recordID);
    }
    @ApiOperation("错题巩固时点击提交答案的API，插入错题巩固的记录，直接传递一个错题的json，后端再进行转换，需要传递错题ID和学生答案")
    @PostMapping("/v1")
    public RedoRecord insertRedo(@RequestBody CuoTiJi cuoTiJi) throws AIstudyException{
        String category=cuoTiJi.getCategory();
        Timestamp currentTimestamp = new Timestamp(System.currentTimeMillis());
        if(category.equals("yuedu")){
            List<RedoRecord>redoRecords=new ArrayList<>();
            List<CuoTiJi>cuoTiJis=cuoTiJi.getCuoTiList();
            int size=cuoTiJis.size();
            for(int i=0;i<size;i++){
                RedoRecord record=new RedoRecord();
                record.setRedoTime(currentTimestamp);
                //获取分析结果
                CuoTiJi tmpCuotiji=cuoTiJis.get(i);
                tmpCuotiji.setContent(cuoTiJi.getContent());
                tmpCuotiji.setCategory(cuoTiJi.getCategory());
                String aiComment= (String) analyseController.analyseUserAnswer(tmpCuotiji);
                //封装分析结果
                record.setRedoAIComment(aiComment);
                record.setCuotiID(tmpCuotiji.getId());
                record.setRedoAnswer(tmpCuotiji.getStuAnswer());
                if(tmpCuotiji.getStuAnswer().equals(tmpCuotiji.getAnswer())){
                    record.setRedoRight(true);
                    //做对了要赋分
                    record.setRedoScore(tmpCuotiji.getScore());
                }
                //更新错题巩固的次数信息
                cuoTiJiService.updateCuotiRedoNum(tmpCuotiji.redoNum+1, tmpCuotiji.getId());
                //将记录封装在列表中
                redoRecords.add(record);
            }
            return redoRecordService.insertRedoRecords(redoRecords);
        }
        else {
            RedoRecord record=new RedoRecord();
            record.setRedoTime(currentTimestamp);
            record.setRedoAnswer(cuoTiJi.getStuAnswer());
            record.setCuotiID(cuoTiJi.getId());
            if(category.equals("zuowen")){
                CompositionDetail detail= (CompositionDetail) analyseController.analyseUserAnswer(cuoTiJi);
//                cuoTiJi.setTransCommentID(detail.getId());
                record.setRedoCompositionID(detail.getId());
                record.setRedoScore(detail.getTotalScore());
            }else if(category.equals("fanyi")){
                TranslateDetail detail= (TranslateDetail) analyseController.analyseUserAnswer(cuoTiJi);
//                cuoTiJi.setTransCommentID(detail.getId());
                record.setRedoTranslationID(detail.getId());
                record.setRedoScore(detail.getTotalScore());
            }else if(category.equals("xuanze")){
                String aiComment= (String) analyseController.analyseUserAnswer(cuoTiJi);
                cuoTiJi.setAiComment(aiComment);
                record.setRedoAIComment(aiComment);
                record.setRedoAnswer(cuoTiJi.getStuAnswer());
                if(cuoTiJi.getStuAnswer().equals(cuoTiJi.getAnswer())){
                    record.setRedoRight(true);
                    record.setRedoScore(cuoTiJi.getScore());
                }
            }
            //更新错题巩固的次数信息
            cuoTiJiService.updateCuotiRedoNum(cuoTiJi.redoNum+1, cuoTiJi.getId());
            //插入数据并返回详细的答题记录
            return redoRecordService.insertRedoRecord(record);
        }
    }

    @ApiOperation("错题巩固时点击提交答案的API，插入错题巩固的记录，直接传递一个错题的json，后端再进行转换，需要传递错题ID和学生答案,返回一个错题Json格式的数据")
    @PostMapping("/v2")
    public CuoTiJi insertRedoGetCuotiJson(@RequestBody CuoTiJi cuoTiJi) throws AIstudyException{
        String category=cuoTiJi.getCategory();
        Timestamp currentTimestamp = new Timestamp(System.currentTimeMillis());
        CuoTiJi cuoTiJi1;
        if(category.equals("yuedu")){
            List<RedoRecord>redoRecords=new ArrayList<>();
            List<CuoTiJi>cuoTiJis=cuoTiJi.getCuoTiList();
            int size=cuoTiJis.size();
            for(int i=0;i<size;i++){
                RedoRecord record=new RedoRecord();
                record.setRedoTime(currentTimestamp);
                //获取分析结果
                CuoTiJi tmpCuotiji=cuoTiJis.get(i);
                tmpCuotiji.setContent(cuoTiJi.getContent());
                tmpCuotiji.setCategory(cuoTiJi.getCategory());
                String aiComment= (String) analyseController.analyseUserAnswer(tmpCuotiji);
                //封装分析结果
                record.setRedoAIComment(aiComment);
                record.setCuotiID(tmpCuotiji.getId());
                record.setRedoAnswer(tmpCuotiji.getStuAnswer());
                if(tmpCuotiji.getStuAnswer().equals(tmpCuotiji.getAnswer())){
                    record.setRedoRight(true);
                    //做对了要赋分
                    record.setRedoScore(tmpCuotiji.getScore());
                }
                //更新错题巩固的次数信息
                cuoTiJiService.updateCuotiRedoNum(tmpCuotiji.redoNum+1, tmpCuotiji.getId());
                //将记录封装在列表中
                redoRecords.add(record);
            }
            cuoTiJi1=redoRecordService.insertRedoRecordsGetCuotiJson(redoRecords);
            userSkillScoreService.updateUserSkillByStuID(cuoTiJi.getStuID());
            return  cuoTiJi1;
        }
        else {
            RedoRecord record=new RedoRecord();
            record.setRedoTime(currentTimestamp);
            record.setRedoAnswer(cuoTiJi.getStuAnswer());
            record.setCuotiID(cuoTiJi.getId());
            if(category.equals("zuowen")){
                CompositionDetail detail= (CompositionDetail) analyseController.analyseUserAnswer(cuoTiJi);
//                cuoTiJi.setTransCommentID(detail.getId());
                record.setRedoCompositionID(detail.getId());
                record.setRedoScore(detail.getTotalScore());
            }else if(category.equals("fanyi")){
                TranslateDetail detail= (TranslateDetail) analyseController.analyseUserAnswer(cuoTiJi);
//                cuoTiJi.setTransCommentID(detail.getId());
                record.setRedoTranslationID(detail.getId());
                record.setRedoScore(detail.getTotalScore());
            }else if(category.equals("xuanze")){
                String aiComment= (String) analyseController.analyseUserAnswer(cuoTiJi);
                cuoTiJi.setAiComment(aiComment);
                record.setRedoAIComment(aiComment);
                record.setRedoAnswer(cuoTiJi.getStuAnswer());
                if(cuoTiJi.getStuAnswer().equals(cuoTiJi.getAnswer())){
                    record.setRedoRight(true);
                    record.setRedoScore(cuoTiJi.getScore());
                }
            }
            //更新错题巩固的次数信息
            cuoTiJiService.updateCuotiRedoNum(cuoTiJi.redoNum+1, cuoTiJi.getId());
            //插入数据并返回详细的答题记录
            cuoTiJi1=redoRecordService.insertRedoRecordGetCuotiJson(record);
        }
        //开启一个新的线程来完成工作
        MyThread thread =new MyThread(userSkillScoreService);
        thread.stuID=cuoTiJi.getStuID();
        thread.start();
        return  cuoTiJi1;
    }

    @ApiOperation("更改重做记录的错因标签和用户批注,需要传递一个完整的json")
    @PutMapping ("/updateUserComment/v1")
    public void updateRecordUserComment(@RequestBody RedoRecord record) throws AIstudyException{
            redoRecordService.updateRecordUserComment(record);
    }

    @ApiOperation("更改重做记录的错因标签和用户批注,需要传递巩固的ID(json中的redoID字段)，更新后的错因标签和批注(可以为空)")
    @PutMapping ("/updateUserComment/v2")
    public void updateRecordUserComment(@ApiParam("用户ID")@RequestParam(value = "stuID") Integer stuID,
                                        @ApiParam("记录ID,json中的redoID字段")@RequestParam(value = "recordID") Integer recordID,
                                        @ApiParam("错因标签")@RequestParam(value = "falseReason",required = false) String falseReason,
                                        @ApiParam("学生备注")@RequestParam(value = "userComment",required = false) String userComment) throws AIstudyException{
        //先获取到详细的数据
        RedoRecord record=redoRecordService.getRecordDetail(recordID);
        //封装错因信息和用户的批注
        if(falseReason!=null)record.setFalseReason(falseReason);
        if(userComment!=null)record.setRedoUserComment(userComment);
        //更新信息
        redoRecordService.updateById(record);
    }
}
